package io.grpc.examples.helloworldtls;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLException;

import io.grpc.ManagedChannel;
import io.grpc.StatusRuntimeException;
import io.grpc.examples.helloworld.GreeterGrpc;
import io.grpc.examples.helloworld.HelloReply;
import io.grpc.examples.helloworld.HelloRequest;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NegotiationType;
import io.grpc.netty.NettyChannelBuilder;
import io.netty.handler.ssl.SMSslClientContextFactory;
import io.netty.handler.ssl.SMSslServerContext;
import io.netty.handler.ssl.SMSslServerContextFactory;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;

public class HelloWorldGMClientTls {
	private final ManagedChannel channel;
	private final GreeterGrpc.GreeterBlockingStub blockingStub;

	private static SslContext build() throws Exception {
//		String caCert = "C:\\Users\\taifu\\Desktop\\临时\\grpc-cert\\gmssl-cert\\ca.crt";
//		String sslCert = "C:\\Users\\taifu\\Desktop\\临时\\grpc-cert\\gmssl-cert\\client.crt";
//		String sslKey = "C:\\Users\\taifu\\Desktop\\临时\\grpc-cert\\gmssl-cert\\client.pem";
//		String enCert = "C:\\Users\\taifu\\Desktop\\临时\\grpc-cert\\gmssl-cert\\client.crt";
//		String enKey = "C:\\Users\\taifu\\Desktop\\临时\\grpc-cert\\gmssl-cert\\client.pem";
//		InputStream caCertIn = new FileInputStream(caCert);
//		InputStream sslCertIn = new FileInputStream(sslCert);
//		InputStream sslKeyIn = new FileInputStream(sslKey);
//		InputStream enCertIn = new FileInputStream(enCert);
//		InputStream enKeyIn = new FileInputStream(enKey);

		InputStream caCertIn = HelloWorldGMServerTls.class.getClassLoader().getResourceAsStream("gmssl-cert/ca.crt");
		InputStream sslCertIn = HelloWorldGMServerTls.class.getClassLoader().getResourceAsStream("gmssl-cert/client.crt");
		InputStream sslKeyIn = HelloWorldGMServerTls.class.getClassLoader().getResourceAsStream("gmssl-cert/client.pem");
		InputStream enCertIn = HelloWorldGMServerTls.class.getClassLoader().getResourceAsStream("gmssl-cert/client.crt");
		InputStream enKeyIn = HelloWorldGMServerTls.class.getClassLoader().getResourceAsStream("gmssl-cert/client.pem");
		
		return SMSslClientContextFactory.build(caCertIn, sslCertIn, sslKeyIn, enCertIn, enKeyIn);
	}

	private static SslContext buildSslContext(String trustCertCollectionFilePath, String clientCertChainFilePath,
			String clientPrivateKeyFilePath) throws Exception {
//		SslContextBuilder builder = GrpcSslContexts.forClient();
//		if (trustCertCollectionFilePath != null) {
//			builder.trustManager(new File(trustCertCollectionFilePath));
//		}
//		if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) {
//			builder.keyManager(new File(clientCertChainFilePath), new File(clientPrivateKeyFilePath));
//		}
//		builder.build();
		return build();
	}

	public HelloWorldGMClientTls(String host, int port, SslContext sslContext) throws SSLException {

		this(NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.TLS).sslContext(sslContext)
				.build());
	}

	HelloWorldGMClientTls(ManagedChannel channel) {
		this.channel = channel;
		blockingStub = GreeterGrpc.newBlockingStub(channel);
	}

	public void shutdown() throws InterruptedException {
		channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
	}

	public void greet(String name) {
		System.out.println("开始发送请求 name=" + name + "");
		HelloRequest request = HelloRequest.newBuilder().setName(name).build();
		HelloReply response;
		try {
			response = blockingStub.sayHello(request);
		} catch (StatusRuntimeException e) {
			e.printStackTrace();
			return;
		}
		System.out.println("============get grpc msg==============");
		System.out.println("接收: " + response.getMessage());
		System.out.println("============get grpc msg==============");
	}

	public static void main(String[] args) throws Exception {
		args = new String[] { "localhost", "7401", "C:\\Users\\taifu\\Desktop\\临时\\grpc-cert\\ca.crt",
				"C:\\Users\\taifu\\Desktop\\临时\\grpc-cert\\client.crt",
				"C:\\Users\\taifu\\Desktop\\临时\\grpc-cert\\client.pem" };
		if (args.length < 2 || args.length == 4 || args.length > 5) {
			System.out.println("USAGE: HelloWorldClientTls host port [trustCertCollectionFilePath] "
					+ "[clientCertChainFilePath] [clientPrivateKeyFilePath]\n  Note: clientCertChainFilePath and "
					+ "clientPrivateKeyFilePath are only needed if mutual auth is desired. And if you specify "
					+ "clientCertChainFilePath you must also specify clientPrivateKeyFilePath");
			System.exit(0);
		}
		{
			HelloWorldGMClientTls client;
			switch (args.length) {
			case 2:
				client = new HelloWorldGMClientTls(args[0], Integer.parseInt(args[1]),
						buildSslContext(null, null, null));
				break;
			case 3:
				client = new HelloWorldGMClientTls(args[0], Integer.parseInt(args[1]),
						buildSslContext(args[2], null, null));
				break;
			default:
				client = new HelloWorldGMClientTls(args[0], Integer.parseInt(args[1]),
						buildSslContext(args[2], args[3], args[4]));
			}

			try {
				String user = "world";
				if (args.length > 0) {
					user = args[0]; /* Use the arg as the name to greet if provided */
				}
				client.greet(user);
			} finally {
				client.shutdown();
			}
		}
	}
}